import 'package:flutter/material.dart';

import 'dart:async';
import 'dart:io';
import 'dart:isolate';

import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_test/flutter_test.dart';

class dioDemo007 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.grey,
        highlightColor: Color.fromRGBO(1, 0, 0, 0.0),//透明
        splashColor: Color.fromRGBO(1, 0, 0, 0.0),//水波纹
      ),
      home: dioDemo007Page(),
    );
  }
}
class dioDemo007Page extends StatefulWidget {
  @override
  _dioDemo007tate createState() => _dioDemo007tate();
}

class _dioDemo007tate extends State<dioDemo007Page> {
  @override
  Widget build(BuildContext context) {
    return Text('_dioDemo007tate');
  }
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    // dioDemo0071();

    // getData();//Future基础
    // testFuture();//Future队列
    // testFuture2();//同级 then比Future队列任务级别高
    // testFuture3();//微任务scheduleMicrotask高于Future
    // testFuture4();//面试题

    // test1();////多线程 隔离 Isolate >thread ，像进程，有独立的内存空间和地址，互不干扰，不会有资源抢夺问题
    // isolateTest(); //多线程 隔离 Isolate 发射器，接收器，
    // computeTest();//compute 多线程，Isolate的封装


//ziji
    // print('do other');
    // getData007();
    // for(int i=1000 ; i<2000;i++){
    //   print(i);
    // }

    // isolateDemo();//如果你返回的是compute的Future，那个这个这个任务就在子Isolate的事件队列中
    // _FuterDd();//then 与微任务
  }
}

void _FuterDd(){
  //then 高于微任务
  Future x = Future((){
    print('A');
    scheduleMicrotask(()=>print('B'));
  });
  x.then((value) => print('C'));
  print('D');
}

void isolateDemo(){
  //无序的
  // for(int i=0;i<5;i++){
  //   Future(() => compute(computefunc1,i)).then((value) => print(i));
  // }

  for(int i=0;i<5;i++){
    loadData1().then((value) => print(i*10));
  }
}
void computefunc1(int count){
  //不在主线程
  // print('computefunc1：'+Isolate.current.debugName);
}
Future loadData1(){
  return Future((){
    //在主线程，闲时执行
    // print('loadData1：'+Isolate.current.debugName);

    //有序的,Future有序添加，Future有序执行，Future有序结束
    compute(computefunc1,1);

    //如果你返回的是compute的Future，那个这个这个任务就在子Isolate的事件队列中
    // return compute(computefunc1,1);// 无序的
  });
}

String _tips = '0';
void getData007() async{
  print('begin'+_tips);

  Future((){//闲时操作
    //耗时操作
    for(int i=0 ; i<1000;i++){
      print(i);
      _tips = '耗时操作';
    }
    print('end'+_tips);
  });
}

void dioDemo0071() {
  //发送网络请求
  //1.创建dio对象
  final dio = Dio();
  //2.下载数据
  var downloadUrl =
      'http://pub.idqqimg.com/pc/misc/groupgift/fudao/CourseTeacher_1.3.16.80_DailyBuild.dmg';

  String savePath = '/Users/hank/123/腾讯课题.dmg';
  //获取temp路径!
  String savePath2 = Directory.systemTemp.path + '/腾讯课堂.dmg';
  print(savePath2);
  download2(dio, downloadUrl, savePath2);
}

void download2(Dio dio, String url, String savePath) {
  dio
      .download(url, (header) {
        return savePath;
      }, onReceiveProgress: showDownloadProgress)
      .whenComplete(() => print('完成'))
      .catchError((e) => print(e));
}

void download1(Dio dio, String url, savePath) {
  dio
      .download(url, savePath, onReceiveProgress: showDownloadProgress)
      .then((value) => print(value))
      .whenComplete(() => print('结束了'))
      .catchError((e) => print(e));
}

void showDownloadProgress(received, total) {
  if (total != -1) {
    print((received / total * 100).toStringAsFixed(0) + "%");
  }
}

//Another way to downloading small file

void computeTest() async {
  print('外部代码1');
  print('外部代码2');

  await compute(func2, 10);
  print('a=$a');
  a = await compute(func2, 20);
  print('a=$a');

  sleep(Duration(seconds: 2));
  print('外部代码3');
}

int func2(int mun) {
  a = mun;
  return 10000;
}

//多线程 隔离 Isolate 发射器，接收器，非常底层
void isolateTest() async {
  print('外部代码1');
  //创建一个port
  ReceivePort portMain = ReceivePort();
  var portThread;

  //创建isolate
  Isolate iso = await Isolate.spawn(func, portMain.sendPort);//发射器
  portMain.listen((message) {//接收器
    portThread = message;//接收数据
    portMain.close();//关闭端口
    iso.kill();//杀掉进程结束
  });

  print('外部代码2');
}
void func(SendPort portMain) {
  ReceivePort portThread = ReceivePort();
  portMain.send(portThread);

  portThread.listen((message) {});//发射数据
}

// //多线程 隔离 Isolate >thread ，像进程，有独立的内存空间和地址，互不干扰，不会有资源抢夺问题
int a = 10;
void test1(){
  print('outside code $a');
  Isolate.spawn(func1, 20);
  sleep(Duration(seconds:2));
  print('inside code $a');
}
void func1(int count){
  a = count;
  print('Isolate code $a');
}

void testFuture4() {
  Future x1 = Future(() => null);
  x1.then((value) {
    print('6');
    scheduleMicrotask(() => print('7'));
  }).then((value) => print('8'));//8高于7，7是创建，8立马执行

  Future x = Future(() => print('1'));
  x.then((value) {
    print('4');
    Future(() => print('9'));
  }).then((value) => print('10'));

  Future(() => print('2'));
  scheduleMicrotask(() => print('3'));

  print('5');
}

//微任务scheduleMicrotask高于Future
void testFuture3() {
  print('外部代码1');
  Future(() => print('A')).then((value) => print('A结束'));
  Future(() => print('B')).then((value) => print('B结束'));
  scheduleMicrotask(() {
    print('微任务A');
    //高于Future
  });
  sleep(Duration(seconds: 2));
  print('外部代码2');
}

//同级 then比Future队列任务级别高
void testFuture2() async {
  Future.wait([
    Future(() {
      return '任务1';
    }),
    Future(() {
      return '任务2';
    }),
  ]).then((value) {
    print(value[0] + value[1]);
  });
}

//队列
void testFuture() async {
  //同级 then比Future队列任务级别高
  Future(() {
    sleep(Duration(seconds: 2));
    return '任务1';
  }).then((value) {
    print('$value结束');
    throw Exception('Error');
    return '$value任务2';
  }).then((value) {
    print('$value结束');
    return '$value任务3';
  }).catchError((e)=>print('结束')).then((value) {
    print('$value 4结束');
    throw Exception('Error2');
    return '$value任务4';
  }).catchError((e)=>print('结束2'));//then函数抛异常会直接到下一个catchError函数
  print('任务添加完毕');
}
//
//  Future(() {
//    sleep(Duration(seconds: 2));
//    return '任务2';
//  }).then((value) {
//    print('$value结束');
//  });

String _data = '0';
getData() async {
  print('开始data=$_data');

  thenFunc(value) {
    print('then 进来了!');
    print('结束data=$value');
  }

  errorFunc(e) {
    print('error来了');
    print('捕获到了:' + e.toString());
  }

  Future future = Future(() {
    //耗时操作
    //1.后面的操作必须是异步才能用await修饰
    //2.当前行数也必须是异步函数 async
//    for (int i = 0; i < 1000000000; i++) {}
    sleep(Duration(seconds: 2)); //确定时间!
  })
      .then((value) {//先error再then error也会掉then,完成一定会执行
        print('then 进来了!');
        print('结束data=$value');
      })
      .catchError(errorFunc)
      .whenComplete(() {
        print('完成了!');
      });

  print('再多干点事情');
}
